﻿#include"XHuffmanTree.h"
#include <fstream>
void XHuffmanTree::addDictionaries(const char* data, const size_t size)
{
	for (size_t i = 0; i < size; i++)
	{
		DictionariesValue& dv = m_dictionaries[(char)(data[i])];
		//创建哈夫曼编码数组
		if (dv.count == 0)
		{
			dv.code = new std::vector<char>;
		}
		dv.count += 1;//计数+1
		//XMap_At(tree->m_dictionaries,data[i],size_t)+=1;
	}
}
void XHuffmanTree::addDictionaries(const std::string fileName, size_t buffer)
{
	//打开待压缩的文件
	std::fstream read(fileName, std::ios::in | std::ios::binary);
	if (!read.is_open())
	{
		std::cout << "File opening failure!" << std::endl;
		return ;
	}
	auto buff = new char[buffer];
	//生成字典
	while (!read.eof())
	{
		auto count = read.read(buff, buffer).gcount();
		addDictionaries(buff, count);
	}
	delete[] buff;
	read.close();
}
size_t XHuffmanTree::dictionariesCount()
{
	return m_dictionaries.size();
}
XDictionaries& XHuffmanTree::dictionaries()
{
	return m_dictionaries;
}
XHfmNode* XHuffmanTree::XHfmTree()
{
	return root;
}
void XHuffmanTree::clearTree()
{
	if (root != NULL)
		XBinaryTree<XHfmNodeData>::clearTree(root);
	root = NULL;
}
void XHuffmanTree::clearCode()
{
	for (auto& value : m_dictionaries)
	{
		auto code = value.second.code;
		if (code != NULL)
			delete code;
	}
	m_dictionaries.clear();
}
void XHuffmanTree::clear()
{
	//清空哈夫曼树
	clearTree();
	//清空哈夫曼编码
	clearCode();
}

XHuffmanTree::XHuffmanTree()
{
}

XHuffmanTree::~XHuffmanTree()
{
	//清空哈夫曼树
	clearTree();
	//清空哈夫曼编码
	clearCode();
}
void XHuffmanTree::init()
{
}
void XHuffmanTree::printTree(XHfmNode* root)
{
	std::cout << "---------------------\n";
	for (auto& node : root->traversing(XBTree::Inorder))
	{
		//if(node->data().code!=NULL)
		std::cout << (int)node->data().ch << " " << node->data().code << " " << node->data().count << "\n";
	};
	std::cout << "---------------------\n";
}

void XHuffmanTree::printDictionaries(XDictionaries& dictionaries)
{
	std::cout << "---------------------\n";
	for (auto& data: dictionaries)
	{
		std::cout << "ch:" << (int)data.first << " count:" << data.second.count << " code:";
		for (auto&c:*data.second.code)
		{
			std::cout << (int)c;
		}
		std::cout << "\n";
	}
	std::cout << "---------------------\n";
}
